<?php

class myDBO_MySQL extends MySQLAbastraction implements myDBO {
	function __construct(){
		parent::__construct();
		GenerateSchemaMap();
		GenerateSchemaProfile();
	}
	function Save($tObjects){
		if(!is_object($tObjects))
			$tObjects = CastArrayAsObject($tObjects);
		$tChangedObjects =  $this->GetChangedDBOs($tObjects,$this->LastResults_Backup);	
		$this->SaveObjects($tChangedObjects);
			
	}
	function SaveObjects($tChangedObjects){
		$sPrimaryIDColumn = $this->PrimaryIDColumn;
		foreach($tChangedObjects as $objCurrent){
			
			$sWhere = "{$this->$sPrimaryIDColumn}='{$objCurrent->$sPrimaryIDColumn}'";
			if(!$this->sqlStatement_Update($this->TableName,(array)$objCurrent,$sWhere)){
				new DatabaseException($this->LastQuery,mysqli_error($this->m_CurrentDbConnection), mysqli_errno($this->m_CurrentDbConnection));
				$ErrorFound = TRUE;
			}
		}
		return (!$ErrorFound)? TRUE : FALSE;
	}
	function GetChangedDBOs($tCurrentObjects,$tBackupObjects){
		ObjectSorter($tCurrentObjects,$this->PrimaryIDColumn);
		ObjectSorter($tBackupObjects,$this->PrimaryIDColumn);
		foreach ($tCurrentObjects as $objArrayKey)
			if($tTMPChanges = $this->CompareObjects($tCurrentObjects[$objArrayKey],$tBackupObjects[$objArrayKey]))
				$tChanged[$objArrayKey] = $tTMPChanges;
		return $tChanged;
	}
	function CompareObjects($objCurrent,$objBackup){
		foreach (get_object_vars($objCurrent) as $objKey=>$objValue){
			if ($objCurrent->$objKey !== $objBackup->$objKey)
				$tChanged[$objKey]= $objValue;
		}
		return $tChanged;
	}
	function LoadAll($tWhere = FALSE, $AsObjects = FALSE){
		if($tWhere){
			foreach ($tWhere as $Column=>$Value)
				$sWhere .= "{$Column}='{$Value} AND";
			$sWhere  = substr($sWhere,0,-3);
		}
		else
			$sWhere = FALSE;
		if(!$this->tLastResults = $this->sqlLoadArray($this->sqlStatement_Select($this->TableName,$sWhere)))
			return FALSE;
		$tResults = LoadAsObjects() ;
		$this->LastResults_Backup = $tResults;
		return $tResults;
	}
	function LoadByPrimaryID($sPrimaryID,$AsObject = FALSE){
		$sWhere = "{$this->PrimaryIDColumn}='{$sPrimaryID}'";
		if(!$this->tLastResults = $this->sqlLoadArray($this->sqlStatement_Select($this->TableName,$sWhere)))
			return FALSE;
		
		$tResults =  LoadAsObjects() ;
		$this->LastResults_Backup = $tResults;
		return $tResults;
	}
	function LoadAsObjects(){
		foreach ($this->tLastResults as $RowID => $RowContent){
			$tSubObjects = $this->{$this->LoadSubObjectsInto};
			$Object = new stdClass;
			foreach ($RowContent as $ColumnName=>$ColumnValue){
				if($ColumnName == $this->PrimaryIDColumn)
					$SubObjectArrayIndex = $ColumnValue;
				$Object->$ColumnName = $ColumnValue;
			}
			$tSubObjects[$SubObjectArrayIndex]= $Object;
		}
		return $tSubObjects;	
	}
	function GenerateSchemaMap(){
		$this->objSchemaColumnMap = new stdClass();
			$tColumnMap = array(
				"Field"		=> 0,
				"Type"		=> 1,
				"NULL"		=> 2,
				"Key"		=> 3,
				"Default"	=> 4,
				"Extra"		=> 5,
			);
		foreach ($tColumnMap as $MapKey=>$MapValue)
			$this->objSchemaColumnMap->$MapKey = $MapValue;
	}
	function GenerateSchemaProfile(){
		$tSchema = $this->sqlLoadArray("DESCRIBE {$this->TableName};");
		foreach ($tSchema as $tRow){
			$ColumnName = $tRow[$this->objSchemaColumnMap->Field];
			if($tRow[$this->objSchemaColumnMap->Key] == "PRI")
				$this->PrimaryIDColumn = $tRow[$ColumnName];
			switch (preg_replace('/^([\w]+)\(.+$/u', '$1', $tRow[$this->objSchemaColumnMap->Type])){
				case "int":
					$this->Schema->$ColumnName = "Numeric";
					break;
				case "set":
					$tSetItems = explode(
									preg_replace('/^([\w]+)\(.+$/u', '$2', $tRow[$this->objSchemaColumnMap->Type])
									,','
								);
					$this->Schema->$ColumnName = $tSetItems;
					break;
				case "varchar":
					$this->Schema->$ColumnName = "String";
				case "text":
				default:
					$this->Schema->$ColumnName = "Text";
			}
					
	}
	
}
function ObjectSorter($tObjectArray,$NumericalKeyname){
		$SorterFunction = 
			function  ($a, $b) use ($NumericalKeyname){ 
				if(  $a->$NumericalKeyname ==  $b->$NumericalKeyname ){ return 0 ; } 
				return ($a->$NumericalKeyname < $b->$NumericalKeyname) ? -1 : 1;
			}; 
		return usort($tObjectArray,$SorterFunction);
}
	
?>
